<?php

abstract class Crud_Form_Element
{
	/**
	 * Wrapped Zend_Form_Element.
	 * 
	 * @var Zend_Form_Element
	 */
	protected $_element;
	
	/**
	 * Create element by given variable.
	 * Can create element via Crud_Db_Table_Column.
	 * Can create element via 
	 * 
	 * @return Crud_Form_Element
	 */
	public static function factory()
	{
		$args = func_get_args();
		$arg = array_shift($args);
		if (!$arg instanceof Crud_Section_Column) {
			throw new Crud_Exception('Cant create element. Unknown arguments given.');
		}
		
		$column = $arg;
		if ($column->isMany2many()) {
			return self::_createMany2many($column);
		}
		
		$name = $column->getName();
		$type = $column->getType();
		$class = $column->getElementClass();
		if ($class) {
			return new $class($column);
		}
		
		if ($column->isFK()) {
			// Column is foreign key
			return new Crud_Form_Element_Column_ForeignKey($column);
		}
		
		if ($type == 'enum') {
			// Column is select with enums
			return new Crud_Form_Element_Column_Enum($column);
		}
		
		$position = strpos($name, 'address');
		if (false !== $position && in_array($type, array('varchar', 'char'))) {
			return new Crud_Form_Element_Column_Map($column);
		}
		
		if (in_array($type, array('text', 'longtext'))) {
			// Column is textarea with wysiwyg
			return new Crud_Form_Element_Column_Text($column);
		}
		
		if ($column->isFile()) {
			return new Crud_Form_Element_Column_File($column);
		}
		
		if (($type == 'tinyint') && $column->isUnsigned()) {
			return new Crud_Form_Element_Column_Tinyint($column);
		}

		if (in_array($type, array('tinyint', 'smallint', 'mediumint', 'int', 'bigint'))) {
			return new Crud_Form_Element_Column_Digits($column);
		}
		
		if (in_array($type, array('float', 'double'))) {
			return new Crud_Form_Element_Column_Float($column);
		}
		
		if ($type == 'date') {
			return new Crud_Form_Element_Column_Date($column);
		}
		
		return new Crud_Form_Element_Column($column);
	}
	
	/**
	 * Create many2many column from factory.
	 * 
	 * @param Crud_Section_Column $column
	 * @return Crud_Form_Element_Many2many
	 */
	private static function _createMany2many($column)
	{
		$table = $column->getSection();
		$m2mTable = $table->getMany2ManyTable($column->getKey());
		
		if ($class = $column->getElementClass()) {
			return new $class($table, $m2mTable);
		}
		
		$table3rd = $m2mTable->getFKColumnNotFor($table)->getFKTable();
		if ($table3rd->hasColumn('parent_id')) {
			return new Crud_Form_Element_Many2many_Tree($table, $m2mTable);
		} else {
			return new Crud_Form_Element_Many2many($table, $m2mTable);
		}
	}
	
	/**
	 * Get wrapped Zend_Form_Element.
	 * 
	 * @return Zend_Form_Element
	 */
	public function getElement()
	{
		return $this->_element;
	}
	
	/**
	 * Set wrapped Zend_Form_Element. 
	 * 
	 * @param Zend_Form_Element
	 * @return Crud_Form_Element
	 */
	public function setElement($element)
	{
		if (!$element instanceof Zend_Form_Element) {
			throw new Crud_Exception('Cant set element. Unknown instance given.');
		}
		
		$this->_element = $element;
		return $this;
	}
}